<template>
  <div id="tags-view-container" class="tags-view-container">
    <scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll" :tagRef="tagRef">
      <span
        v-for="(tag, index) in tabsArr"
        ref="tagRef"
        :key="tag.path"
        :path="tag.path"
        :class="isActive(tag)?'active':''"
        class="tags-view-item"
        @click="menuClick(tag, $event)"
        @contextmenu.prevent="openMenu(tag, index, $event)"
      >
        {{ tag.name }}
        <el-icon class="close" v-if="!tag.isClosed" @click.stop="closeClickMenu(tag, index, $event)"><Close /></el-icon>
      </span>
    </scroll-pane>
    <transition name="fade">
      <ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
        <li v-if="isActive(selectedTag)" @click="refreshSelectedTag(selectedTag)">刷新页面</li>
        <li v-if="!selectedTag.isClosed" @click="closeMenuTags(selectedTag, 'current')">关闭当前</li> 
        <li v-if="!selectedTag.isClosed" @click="closeMenuTags(selectedTag, 'left')">关闭左侧</li>
        <li @click="closeMenuTags(selectedTag, 'other')">关闭其他</li>
        <li @click="closeMenuTags(selectedTag, 'right')">关闭右侧</li>
        <li @click="closeMenuTags(selectedTag, 'all')">关闭所有</li>
      </ul>
    </transition>
  </div>
</template>

<script>
import {reactive, toRefs, computed, nextTick, watch, ref} from 'vue'
import {useStore} from 'vuex'
import {useRoute, useRouter} from 'vue-router'
import {Close} from '@element-plus/icons-vue'
import ScrollPane from './ScrollPane'

export default {
  name: 'TagsViewName',
  components: { ScrollPane, Close },
  setup() {
    const store = useStore()
    const $route = useRoute()
    const $router = useRouter()
    const tagRef = ref(null)
    const scrollPane = ref(null)
    const data = reactive({
      visible: false,
      top: 0,
      left: 0,
      selectedTag: {},
      selectedIndex: 0,
      affixTags: []
    })

    const tabsArr = computed(()=>store.getters.getTabsArr)

    function isActive(route) {
      return route.path === $route.path
    }
    function refreshSelectedTag(view) {
      nextTick(() => {
        $router.replace({
          name: 'RedirectName',
          params: {
            path: view.path
          }
        })
      })
    }
    function closeMenuTags(view, type) {
      let path = view.path
      let index = 0
      let isSave = path == $route.path
      for(var i= 0; i<tabsArr.value.length; i++){
        if(tabsArr.value[i].path == path){
          index = i
          break
        }
      }
      if(type == 'current'){
        // 关闭当前
        this.closeClickMenu(view, index)
      }else if(type == 'left'){
        let noClosed = []
        for(var i = 0; i < tabsArr.value.length; i++){
          if(i < index && tabsArr.value[i].isClosed && path != tabsArr.value[i].path){
            noClosed.push(tabsArr.value[i])
          }
        }
        tabsArr.value.splice(0, index)
        store.commit('setTabsArr', [...noClosed, ...tabsArr.value])
        if(!isSave){
          $router.replace(path)
        }
      }else if(type == 'other'){
        let noClosed = []
        for(var i = 0; i < tabsArr.value.length; i++){
          if(tabsArr.value[i].isClosed && path != tabsArr.value[i].path){
            noClosed.push(tabsArr.value[i])
          }
        }
        store.commit('setTabsArr', [...noClosed, view])
        if(!isSave){
          $router.replace(path)
        }
      }else if(type == 'right'){
        let noClosed = []
        for(var i = 0; i < tabsArr.value.length; i++){
          if(i > index && tabsArr.value[i].isClosed && path != tabsArr.value[i].path){
            noClosed.push(tabsArr.value[i])
          }
        }
        tabsArr.value.splice(index+1, tabsArr.value.length - index -1)
        store.commit('setTabsArr', [...tabsArr.value, ...noClosed])
        if(!isSave){
          $router.replace(path)
        }
      }else if(type == 'all'){
        let noClosed = []
        for(var i = 0; i < tabsArr.value.length; i++){
          if(tabsArr.value[i].isClosed){
            noClosed.push(tabsArr.value[i])
          }
        }
        store.commit('setTabsArr', [...noClosed])
        if(noClosed.length){
          $router.replace(noClosed[0].path)
        }
      }
      // store.dispatch('closeOtherRoute', {path: view.routerName, type, nowRoute: $route})
    }
    function closeClickMenu(tag, index) {
      tabsArr.value.splice(index, 1)
      store.commit('setTabsArr', tabsArr)
      if(tag.path == $route.path){
        const nextTab = tabsArr.value[index + 1] || tabsArr.value[index - 1]
        if(nextTab){
          $router.replace(nextTab.path)
        }
        // $router.go(-1)
      }
    }
    function menuClick(tag) {
      if($route.path != tag.path){
        $router.push(tag.path)
      }
    }
    function openMenu(tag, index, e) {
      data.top = e.y - e.layerY + 30
      data.left = e.x - e.layerX + 21
      data.visible = true
      data.selectedTag = tag
      data.selectedIndex = index
    }
    function closeMenu() {
      data.visible = false
    }
    function handleScroll() {
      closeMenu()
    }

    const moveToCurrentTag = () => {
      nextTick(() => {
        for (const tag of tagRef.value) {
          if (tag.attributes.path.value === $route.path) {
            scrollPane.value.moveToTarget(tag)
            break
          }
        }
      })
    }

    watch(()=>data.visible, (value)=>{
      if (value) {
        document.body.addEventListener('click', closeMenu)
      } else {
        document.body.removeEventListener('click', closeMenu)
      }
    })
    watch(()=>$route.path, (value)=>{
      moveToCurrentTag()
    })
    return {
      tagRef,
      scrollPane,
      ...toRefs(data),
      tabsArr,
      isActive,
      refreshSelectedTag,
      closeMenuTags,
      closeClickMenu,
      menuClick,
      openMenu,
      closeMenu,
      handleScroll,
    }
  }
}
</script>

<style lang="scss" scoped>
.fade-enter-active, .fade-leave-active {
  // transition: opacity .5s;
  transition: all .3s ease;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
.tags-view-container {
  height: 42px;
  width: 100%;
  background: #f5f7f9;
  // border-bottom: 1px solid #d8dce5;
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
  .tags-view-wrapper {
    .tags-view-item {
      display: inline-block;
      position: relative;
      cursor: pointer;
      color: #808695;
      background: #fff;
      height: 32px;
      line-height: 32px;
      font-size: 14px;
      margin-left: 6px;
      margin-top: 4px;
      border: none;
      padding: 0 10px;
      border-radius: 3px;

      &:first-of-type {
        margin-left: 15px;
      }
      &:last-of-type {
        margin-right: 15px;
      }
      &.active {
        background-color: #fff;
        color: #2d8cf0;
        border-color: #2d8cf0;
      }
      .close{
        top: 2px;
      }
    }
  }
  .contextmenu {
    margin: 0;
    background: #fff;
    z-index: 3000;
    position: absolute;
    list-style-type: none;
    padding: 5px 0;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 400;
    color: #333;
    box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
    li {
      margin: 0;
      padding: 7px 16px;
      cursor: pointer;
      &:hover {
        background: #eee;
      }
    }
  }
}
</style>

<style lang="scss">
//reset element css of el-icon-close
.tags-view-wrapper {
  .tags-view-item {
    .el-icon-close {
      width: 18px;
      height: 18px;
      vertical-align: 2px;
      border-radius: 50%;
      text-align: center;
      transition: all .3s cubic-bezier(.645, .045, .355, 1);
      transform-origin: 100% 50%;
      &:before {
        transform: scale(.6);
        display: inline-block;
        vertical-align: -3px;
      }
      &:hover {
        background-color: #b4bccc;
        color: #fff;
      }
    }
  }
}
</style>
